#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <algorithm>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::ifstream;
using std::ofstream;

#define ERROR_CHECK(cond, msg, cleanup) \
    do{ \
        if(cond) { \
            std::cerr << "Error:" << msg << "(" << __FILE__ << ":" << __LINE__ << ")" << std::endl; \
            cleanup; \
            return; \
        } \
    }while(0)

struct Record
{
    string _word;
    int _frequency;
};

class Dictionary
{
public:
    void read(const std::string &filename);
    void store(const std::string &filename);
private:
    void sortedInsert(string &vcb);
    vector<Record> _dict;
};

/*
void Dictionary::sortedInsert(string &str){
    auto it = lower_bound(_dict._word.begin(), _dict._word.end(), str);
    _dict.insert(it, str);
    _dict[it]._frequency++;
}
*/

void Dictionary::sortedInsert(string &str){
    auto it = lower_bound(  // 查找插入位置
        _dict.begin(),      // 起点
        _dict.end(),        // 终点
        str,                // 要插入的值
        [](const Record& rec, const string& str){     // 自定义比较规则
            return rec._word < str;                   // 返回第一个不满足 rec._word < str的元素，即rec._word >= str的位置，将str插入至rec._word前
        }      
    );

    if(it != _dict.end() && it->_word == str){
        it->_frequency++;   // 已存在则频率 + 1
    }else{
        _dict.insert(it, {str, 1});     // 不存在则插入记录
    }
}

void Dictionary::read(const std::string &filename){
    // 1. 打开文件
    ifstream ifs(filename);
    ERROR_CHECK(!ifs.good(), "ifstream is not good", ifs.close());

    // 2. 存放单词
    string word;
    while(ifs >> word){
        sortedInsert(word);
    }

//    // 3. 打印到屏幕
//    for(int i = 0; i < _dict.size(); i++){
//        cout << _dict[i]._word << "." << _dict[i]._frequency << endl;
//    }

    // 3. 关闭文件
    cout << endl;
    ifs.close();
}

void Dictionary::store(const std::string &filename){
    // 1. 打开文件
    ofstream ofs(filename, std::ios::app);
    ERROR_CHECK(!ofs.good(), "ofs is not good", ofs.close());

    // 2. 写入文件
//    for(int i = 0; i < _dict.size(); i++){
//        ofs << _dict[i]._word << " "
//            << _dict[i]._frequency
//            << endl;
//    }
    auto it = _dict.begin();
    while(it != _dict.end()){
        ofs << it->_word << " " 
            << it->_frequency 
            << endl;
        ++it;
    }

    ofs.close();
}

int main(){
    Dictionary dict;

    dict.read("The_Holy_Bible.txt");
    dict.store("01_Statistic.txt");
}
